#ifndef GENERIC_DBFILE_H
#define GENERIC_DBFILE_H

#include "TwoWayList.h"
#include "Record.h"
#include "Schema.h"
#include "File.h"
#include "Comparison.h"
#include "ComparisonEngine.h"
#include "BigQ.h"
#include <iostream>
#include <cstring>
#include <pthread.h>
#include <string>

class GenericDBFile{

protected:
    int curPageInFile;
    File dbFile;
    Page dbPage;
    Record curRecord;
    string file_path;
public:

    virtual int Create (char *f_path);
    virtual int Open (char *f_path);
    virtual int Close ()=0;
    virtual void MoveFirst()=0;
    virtual void Add (Record &addMe)=0;
    virtual void Load (Schema &mySchema, char *loadpath)=0;
    virtual int GetNext (Record &fetchMe)=0;
    virtual void AdditionAddPage()=0;
    virtual int GetNext (Record &fetchMe, CNF &applyMe, Record &literal)=0;
    virtual ~GenericDBFile();

};

class HeapDBFile : public GenericDBFile{

private:

public:
    HeapDBFile();
    int Create (char *f_path);
    int Open (char *f_path);
    int Close ();
    void Load (Schema &mySchema, char *loadpath);
    void MoveFirst();
    void AdditionAddPage();
    void Add (Record &addMe);
    int GetNext (Record &fetchMe);
    int GetNext (Record &fetchMe, CNF &applyMe, Record &literal);
    ~HeapDBFile();


};

class SortedDBFile : public GenericDBFile{
        BigQ *bigq;
        SortInfo *sortInfo;
        int buffsz; // pipe cache size
        Pipe *in;
        Pipe *out;
        bool queryBuilt;
        bool sortOrderExists;
        OrderMaker *query;
        Page midPage;
        bool reading;
        int pipecount;
        OrderMaker sortorder;

public:
    SortedDBFile();
    SortedDBFile(SortInfo *info);
    int Create (char *f_path);
    int Open (char *f_path);
    int Close ();
    void Load (Schema &mySchema, char *loadpath);
    void MoveFirst();
    void Add (Record &addMe);
    void AdditionAddPage();
    int BuildQuery(OrderMaker *cnfOrder, OrderMaker *sortOrder);
    void InitialBigQ();
    int GetNextQuery(Record &fetchme, CNF &cnf, Record &literal);
    int SequentialGetNext (Record &fetchme, CNF &cnf, Record &literal);
    int BinarySearch(Record& fetchme,CNF &cnf,Record &literal);
    int Merge();
    int GetNext (Record &fetchMe);
    int GetNext (Record &fetchMe, CNF &applyMe, Record &literal);
    void *producer (void *arg, Record &addme);
    void *consumer (void *arg);
    ~SortedDBFile();

};

#endif
